package org.example;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.extra.pinyin.PinyinUtil;
import lombok.extern.java.Log;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.*;

@Log
public class Main {
    final static String[] imageFormat = {"jpg", "png", "gif", "ico", "bmp", "jpeg", "tga", "tif", "webp"};
    final static String[] videoFormat = {"mp4", "mkv", "flv", "avi", "3gp", "mov", "Ogg", "swf", "vob", "webm", "wmv", "mpg"};
    final static int LOOSE = 1;//宽松
    final static int STRICT = 2;//严格
    final static Logger logger = LoggerFactory.getLogger(Main.class);

    public static void main(String[] args) {
        System.out.println("————————————欢迎使用TR工具脚本————————————");
//        logger.info("看到我就没乱码");
        //        System.getProperties().forEach((k,v)->System.out.println(k+"="+v));
        tips();
        nav();
    }

    /**
     * 方法：测试方法
     */
    private static void testTest(){
        Scanner sc = new Scanner(System.in);
        System.out.println("请将需要分发的文件拖拽到此处。");
        //获取需要分发的文件对象
        String fileStr = sc.nextLine();

/*        String utf8String = null; // 使用 UTF-8 编码方式重新构造字符串
        try {
            utf8String = new String(fileStr.getBytes("GBK"), StandardCharsets.UTF_8);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

        File distributeFile = new File(utf8String);*/


//        System.out.println(distributeFile);
        System.out.println(fileStr);
        logger.info(fileStr);

//        FileReader fileReader = new FileReader(distributeFile);
    }

    /**
     * 方法：导航
     */
    private static void nav() {
        logger.trace("启动==============================================================");
/*        logger.debug("=debug=");
        logger.info("=info=");
        logger.warn("=warn=");
        logger.error("=error=");*/
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.print("#：");
            String scStr = sc.nextLine();
            switch (scStr) {
                case "1" -> itemFirst();
                case "2" -> itemSecond();
                case "3" -> itemThird();
                case "4" -> itemFourth();
                case "5" -> itemFifth();
                case "6" -> itemSixth();
                case "7" -> itemSeventh();
                case "0" -> command();
                case "tip", "tips" -> tips();
                case "ex", "exs" -> ex();
                case "test" -> testTest();
                case "quit", "exit" -> System.exit(0);
                default -> logger.warn("选择有误，请重新选择");
            }
        }
    }

    /**
     * 方法：提示词
     */
    private static void command() {
        System.out.println("──────────────────指令──────────────────");
        System.out.println("Ⅰ.退出[quit]");
        System.out.println("Ⅱ.展现导航[tip]");
        System.out.println("Ⅲ.功能说明[ex]");
//        System.out.println("Ⅰ.Ⅱ.Ⅲ.Ⅳ.Ⅴ.Ⅵ.Ⅶ.Ⅷ.Ⅸ.Ⅹ.");
        System.out.println("────────────────────────────────────────");
    }

    /**
     * 方法：提示词
     */
    private static void tips() {
        System.out.println("──────────────────导航──────────────────");
        System.out.println("1.增加[图片数量 视频数量 文件大小]后缀");
        System.out.println("2.增加[图片数量 视频数量]后缀");
        System.out.println("3.删除[]后缀");
        System.out.println("4.敏感词替换(宽松)");
        System.out.println("5.敏感词替换(严格)");
        System.out.println("6.Word => txt");
        System.out.println("7.文件分发式粘贴");
        System.out.println("0.查看命令");
        System.out.println("────────────────────────────────────────");
    }

    /**
     * 方法：提示词
     */
    private static void ex() {
        System.out.println("──────────────────说明──────────────────");
        System.out.println("1.增加[图片数量 视频数量 文件大小]后缀 【字面意思】");
        System.out.println("2.增加[图片数量 视频数量]后缀 【字面意思】");
        System.out.println("3.删除[]后缀 【字面意思】");
        System.out.println("4.敏感词替换(宽松) 【将连续的汉字替换为拼音】");
        System.out.println("5.敏感词替换(严格) 【将连续的汉字替换为拼音，且只保留首字母】");
        System.out.println("6.Word => txt 【将word文档转换为txt文档】");
        System.out.println("7.文件分发式粘贴 【将拖入的文件分发到每个文件夹的每个角落，除了第一层文件夹】");
        System.out.println("────────────────────────────────────────");
    }

    /**
     * 方法：item1 增加[图片数量 视频数量 文件大小]后缀
     */
    private static void itemFirst() {
        //获取工作目录路径
        File file = new File(System.getProperty("user.dir"));
        List<File> dirs = getDirs(file);
        for (File dir : dirs) {
            fileNameAdd1(dir);
        }
        logger.info("提示————已成功处理" + dirs.size() + "个文件夹。");
    }

    /**
     * 方法：item2 增加[图片数量 视频数量]后缀
     */
    private static void itemSecond() {
        //获取工作目录路径
        File file = new File(System.getProperty("user.dir"));
        List<File> dirs = getDirs(file);
        for (File dir : dirs) {
            fileNameAdd2(dir);
        }
        logger.info("提示————已成功处理" + dirs.size() + "个文件夹。");
    }

    /**
     * 方法：item3 删除[]后缀
     */
    private static void itemThird() {
        File file = new File(System.getProperty("user.dir"));
        List<File> dirs = getDirs(file);
        for (File dir : dirs) {
            fileNameRemove(dir);
        }
        logger.info("提示————已成功处理" + dirs.size() + "个文件夹。");
    }

    /**
     * 方法：item4 敏感词替换(宽松)
     */
    private static void itemFourth() {
        File[] ls = FileUtil.ls(System.getProperty("user.dir"));
//        System.out.println(Arrays.toString(ls));
        int count = fileNameRe(ls, LOOSE);
        logger.info("提示————已成功处理" + count + "个文件。");
    }


    /**
     * 方法：item5 敏感词替换(严格)
     */
    public static void itemFifth() {
        File[] ls = FileUtil.ls(System.getProperty("user.dir"));
//        System.out.println(Arrays.toString(ls));
        int count = fileNameRe(ls, STRICT);
        logger.info("提示————已成功处理" + count + "个文件。");
    }

    /**
     * 方法：item6 docx=>txt
     */
    public static void itemSixth() {
        //获取工作目录路径
        File file = new File(System.getProperty("user.dir"));
        //获取工作目录文件
        List<File> files = getFile(file);
//        System.out.println(files);
        //计数器
        int count = 0;
        //获得当前目录下的所有文件
        for (File f : files) {
//            System.out.println(f.getName());
            //找到.docx结尾的文件
            if (f.getName().endsWith(".docx")) {
//                System.out.println("找到文件");
                StringBuilder stringBuilder = ReadWord(f);
//                System.out.println(stringBuilder);
                String result = f.toString().replace("docx", "txt");
//                System.out.println(result);
                FileWriter fileWriter = new FileWriter(result);
                fileWriter.write(stringBuilder.toString());
                count++;
            }
        }
        logger.info("提示————已成功输出" + count + "个文件。");
    }

    /**
     * 方法：item7 文件分发式粘贴
     */
    public static void itemSeventh() {
        Scanner sc = new Scanner(System.in);
        System.out.println("请将需要分发的文件拖拽到此处或者将地址粘贴到此处。");
        //获取需要分发的文件对象
        String fileStr = sc.nextLine();
        String cleanedPath = fileStr.replace("\"", "");  // 移除所有双引号
        File distributeFile = new File(cleanedPath);
//        System.out.println(distributeFile);

        FileReader fileReader = new FileReader(distributeFile);

        int pasteCount = 0;
        //获取工作目录路径
        File file = new File(System.getProperty("user.dir"));
        //获取工作目录文件夹
        List<File> dirs = getDirs(file);
        for (File dir : dirs) {
            pasteCount += recursionPaste(dir, fileReader, distributeFile.getName());
        }
        logger.info("提示————成功，共计粘贴" + pasteCount + "次。");
    }

    private static int recursionPaste(File dir, FileReader fileReader, String fileName) {
        int pasteCount = 0;
        File[] ls = FileUtil.ls(dir.getPath());
        boolean flag = false;
        for (File f : ls) {
            if (f.isFile()) {
                flag = true;
            } else {
                int i = recursionPaste(f, fileReader, fileName);
                pasteCount += i;
            }
        }
        if (flag) {
            String path = dir.getPath() + "\\" + fileName;
            FileWriter fileWriter = new FileWriter(path);
            fileWriter.write(fileReader.readString());
            pasteCount++;
            logger.trace(path + "粘贴成功！");
        }
        return pasteCount;
    }


    /**
     * 方法：格式化输出字符串
     * 参数：要输出的字符串
     */
    private static void formatPrint(String[] text) {
        System.out.println("┌────────────────────────────────────────");
        for (String s : text) {
            System.out.println("│" + s);
        }
        System.out.println("└────────────────────────────────────────");
    }

    /**
     * 方法：获取目录下一级的所有文件夹
     * 参数：目录
     * 返回值：文件目录集合
     */
    private static List<File> getDirs(File file) {
        //文件集合，将该文件夹中的文件夹全部放到集合当中
        List<File> files = new ArrayList<>();
        //获取工作目录文件夹
        File[] ls = FileUtil.ls(file.getPath());
//        System.out.println(Arrays.toString(ls));
        for (File f : ls) if (!f.isFile()) files.add(f);
        return files;
    }

    /**
     * 方法：获取目录文件
     * 参数：目录
     * 返回值：文件列表集合
     */
    private static List<File> getFile(File file) {
        //文件集合，将该文件夹中的文件夹全部放到集合当中
        List<File> files = new ArrayList<>();
        //获取工作目录文件夹
        File[] ls = FileUtil.ls(file.getPath());
//        System.out.println(Arrays.toString(ls));
        for (File f : ls) if (f.isFile()) files.add(f);
        return files;
    }

    /**
     * 方法：递归获取目录所有文件
     * 参数：目录
     * 返回值：文件列表集合
     */
    private static List<File> getAllFile(File file) {
        //文件集合，将该文件夹中的文件全部放到集合当中
        List<File> files = new ArrayList<>();
        //获取工作目录文件&文件夹
        File[] ls = FileUtil.ls(file.getPath());
//        System.out.println(Arrays.toString(ls));
        for (File f : ls) {
            if (f.isFile()) {
                files.add(f);
            } else {
                List<File> interFiles = getAllFile(f);
                files.addAll(interFiles);
            }
        }
        return files;
    }

    /**
     * 方法：读取word文档
     * 返回值：整体字符串
     */
    public static StringBuilder ReadWord(File file) {
        StringBuilder stringBuilder = new StringBuilder();
        try {
            FileInputStream fis = new FileInputStream(file);
            XWPFDocument document = new XWPFDocument(fis);
            // 读取所有段落
            List<XWPFParagraph> paragraphs = document.getParagraphs();
            for (XWPFParagraph para : paragraphs) {
                stringBuilder.append(para.getText());
                stringBuilder.append("\n");
            }
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return stringBuilder;
    }

    /**
     * 方法：增加文件名后缀方式【1】
     */
    private static void fileNameAdd1(File file) {
        List<File> allFiles = getAllFile(file);
        int imgCount = 0;
        int videoCount = 0;
        Long fileTotalSize = 0L;
        for (File af : allFiles) {
            for (int i = 0; i < imageFormat.length; i++) {
                if (af.getName().toLowerCase().endsWith("." + imageFormat[i].toLowerCase())) {
                    imgCount++;
                }
            }
            for (int i = 0; i < videoFormat.length; i++) {
                if (af.getName().toLowerCase().endsWith("." + videoFormat[i].toLowerCase())) {
                    videoCount++;
                }
            }
            fileTotalSize += af.length();
        }

        String fileInfo = " [";
        if (imgCount > 0) fileInfo += imgCount + "P ";
        if (videoCount > 0) fileInfo += videoCount + "V ";
        fileInfo += unitConversion(fileTotalSize) + "]";
        FileUtil.rename(file, file.getName() + fileInfo, true);
    }

    /**
     * 方法：增加文件名后缀方式【2】
     */
    private static void fileNameAdd2(File file) {
        List<File> allFiles = getAllFile(file);
        int imgCount = 0;
        int videoCount = 0;
        for (File af : allFiles) {
            for (int i = 0; i < imageFormat.length; i++) {
                if (af.getName().toLowerCase().endsWith("." + imageFormat[i].toLowerCase())) {
                    imgCount++;
                }
            }
            for (int i = 0; i < videoFormat.length; i++) {
                if (af.getName().toLowerCase().endsWith("." + videoFormat[i].toLowerCase())) {
                    videoCount++;
                }
            }
        }
        String fileInfo = " [";
        if (imgCount > 0 && videoCount > 0) {
            FileUtil.rename(file, file.getName() + " [" + imgCount + "P " + videoCount + "V]", true);
        } else if (imgCount > 0 && videoCount == 0) {
            FileUtil.rename(file, file.getName() + " [" + imgCount + "P]", true);
        } else if (imgCount == 0 && videoCount > 0) {
            FileUtil.rename(file, file.getName() + " [" + videoCount + "V]", true);
        }
    }

    /**
     * 方法：重命名方式
     */
    private static int fileNameRe(File[] ls, int level) {
        int count = 0;
        for (File f : ls) {
            StringBuilder resultName = new StringBuilder();
            boolean bFlag = false;
            int sFlag = 0;
            for (int i = 0; i < f.getName().length(); i++) {
                //如果是汉字
                if (Character.UnicodeScript.of(f.getName().charAt(i)) == Character.UnicodeScript.HAN) {
                    //如果flag是1，说明是连续的第二个汉字
                    if (sFlag == 1) {
                        String pinyin = PinyinUtil.getPinyin(f.getName().charAt(i));
                        if (level == LOOSE) {
                            resultName.append(pinyin);
                        } else if (level == STRICT) {
                            resultName.append(pinyin.charAt(0));
                        }
                        bFlag = true;
                        sFlag = 0;
                    } else {
                        sFlag++;
                        resultName.append(f.getName().charAt(i));
                    }
                } else {
                    sFlag = 0;
                    resultName.append(f.getName().charAt(i));
                }
            }
//            System.out.println(resultName);
            if (bFlag) {
                FileUtil.rename(f, resultName.toString(), true);
                count++;
            }
        }
        return count;
    }

    /**
     * 方法：清除文件[]后缀
     */
    private static void fileNameRemove(File file) {
        if (!file.isFile() && file.getName().endsWith("]"))
            FileUtil.rename(file, file.getName().split(" \\[")[0], true);
    }

    /**
     * 方法：转换单位
     * 参数：文件大小，单位B
     * 返回值：转换为合适的单位的字符串
     */
    private static String unitConversion(long size) {
        int count = 0;
        String[] unit = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"};
        long tSize = size;
        while (tSize >= 1024) {
            tSize /= 1024;
            count++;
        }
        DecimalFormat df = new DecimalFormat("#.##");
        BigDecimal b = new BigDecimal(size);
        long d = 1;
        if (count >= 1) for (int i = 0; i < count; i++) d *= 1024L;

        BigDecimal divide = b.divide(new BigDecimal(d), 2, RoundingMode.DOWN);
        return df.format(divide) + unit[count];
    }

}
